package net.gianrishandy.jbase.component;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.event.EventListenerList;
import javax.swing.table.TableRowSorter;

import net.gianrishandy.jbase.component.adapter.DataListAdapter;
import net.gianrishandy.jbase.component.event.DataListEvent;
import net.gianrishandy.jbase.component.listener.DataListListener;
import net.gianrishandy.jbase.model.DataColumn;
import net.gianrishandy.jbase.model.DataRow;
import net.gianrishandy.jbase.model.DataTable;

/**
 * @author Gian Rishandy
 *
 */
public class DataList extends JDialog {
	
	private static final long serialVersionUID = 1L;
	private final JPanel contentPanel = new JPanel();
	private JTable tableFilter;
	private JTable tableData;
	private EventListenerList listenerList = new EventListenerList();
	private TableRowSorter<DataTable> sorter;
	private DataTable dataTable;

	public DataList() {
		setIconImage(Toolkit.getDefaultToolkit().getImage(DataList.class.getResource("/net/gianrishandy/jbase/images/tj.png")));
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setTitle("DataList");
		setModal(true);
		setBounds(100, 100, 600, 400);
		setLocationRelativeTo(null);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(null);
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(new BorderLayout(0, 0));
		
		JPanel panelFilter = new JPanel();
		panelFilter.setPreferredSize(new Dimension(10, 75));
		contentPanel.add(panelFilter, BorderLayout.NORTH);
		panelFilter.setLayout(new BorderLayout(0, 0));
		
		JScrollPane scrollPaneFilter = new JScrollPane();
		panelFilter.add(scrollPaneFilter, BorderLayout.CENTER);
		
		tableFilter = new JTable();
		tableFilter.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				tblFilterKeyReleased(e);
			}
		});
		scrollPaneFilter.setViewportView(tableFilter);
		
		JPanel panelData = new JPanel();
		contentPanel.add(panelData, BorderLayout.CENTER);
		panelData.setLayout(new BorderLayout(0, 0));
		
		JScrollPane scrollPaneData = new JScrollPane();
		panelData.add(scrollPaneData, BorderLayout.CENTER);
		
		tableData = new JTable();
		tableData.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				tblDataKeyPressed(e);
			}
		});
		tableData.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				tblDataMouseClicked(e);
			}
		});
		scrollPaneData.setViewportView(tableData);
	}
	
	/**
	 * Show DataList
	 * 
	 * @throws Exception
	 */
	public void showDataList() throws Exception{
		DataTable filterDataTable = dataTable.clone();
		DataTable dataDataTable = dataTable.clone();
		
		filterDataTable.setRowCount(0);
		filterDataTable.addRow();
		tableFilter.setModel(filterDataTable);
		
		tableData.setModel(dataDataTable);
		tableData.setRowSorter(getRowSorter());
		
		if(filterDataTable.getColumnCount() > 6){
			tableFilter.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
			tableData.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		}else{
			tableFilter.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
			tableData.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
		}
		
		setVisible(true);

	}
	
	/**
	 * Get DataTable from DataList
	 * 
	 * @return DataTable
	 */
	public DataTable getDataTable() {
		return dataTable;
	}

	/**
	 * Set DataTable into DataList
	 * 
	 * @param dataTable
	 */
	public void setDataTable(DataTable dataTable) {
		this.dataTable = dataTable;
	}
	
	private void proccesResult(){
		DataTable datatable = (DataTable)tableData.getModel();
		
		DataRow ldatarow = new DataRow();
		for(int i=0;i<datatable.getColumnCount();i++){
			Object value = tableData.getValueAt(tableData.getSelectedRow(), i);
			ldatarow.add(value);
		}
		ldatarow.setColumns(datatable.getDataColumns());
		
		DataListEvent event = new DataListEvent(this);
		event.setDataRow(ldatarow);
		
		dataListActionPerformed(event);
		dispose();
	}
	
	private void tblDataMouseClicked(MouseEvent evt){
		if(evt.getClickCount() == 1){
			proccesResult();
		}		
	}
	
	private void tblDataKeyPressed(KeyEvent evt){
		if(evt.getKeyCode() == KeyEvent.VK_ENTER){
			proccesResult();
		}
	}
	
	private void tblFilterKeyReleased(KeyEvent evt) {
		filterTable();
	}
	
	private void filterTable(){
		List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object,Object>>();
		int col = tableFilter.getColumnCount();
		for(int c=0;c<col;c++){
			String columnname = tableFilter.getColumnName(c);
			DataTable datatable = (DataTable)tableFilter.getModel();
			DataColumn datacolumn = datatable.getColumn(datatable.findColumn(columnname));
			Object value = tableFilter.getValueAt(0, c);
			if(value != null){
				if(!value.toString().equalsIgnoreCase("")){
					if(datacolumn.getColumnClass() == Date.class){
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
						String date = sdf.format((Date)value);
						filters.add(RowFilter.regexFilter(date, c));
					}else{
						filters.add(RowFilter.regexFilter("(?i)" + value.toString(), c));
					}
				}
			}
		}
		RowFilter<Object, Object> filter = RowFilter.andFilter(filters);
		getRowSorter().setRowFilter(filter);
	}
	
	private TableRowSorter<DataTable> getRowSorter(){
		if (sorter == null) {
			sorter = new TableRowSorter<DataTable>((DataTable)tableData.getModel());
		}
		return sorter;
	}
	
	public void addDataListListener(DataListAdapter listener){
		listenerList.add(DataListListener.class, listener);
	}
	
	public void removeDataListListener(DataListAdapter listener){
		listenerList.remove(DataListListener.class, listener);
	}
	
	private void dataListActionPerformed(DataListEvent evt){
		Object[] list = listenerList.getListenerList();
		for(int i=0;i<list.length;i+=2){
			if(list[i] == DataListListener.class){
				((DataListAdapter)list[i+1]).actionPerformed(evt);
			}
		}
	}

}
